package com.yook;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

class Account {
    private String name;    // 账户名称
    private int asset;    // 账户资金
    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); // 读写锁

    public Account(String name, int asset) {    // 构造方法
        this.name = name;
        this.asset = asset;    // 属性赋值
    }

    public void save(int asset) { // 写锁操作方法
        this.readWriteLock.writeLock().lock();    // 独占的写锁
        try {
            this.asset += asset;    // 账户资金累加
            TimeUnit.SECONDS.sleep(1);    // 模拟延迟
            System.out.println("[" + Thread.currentThread().getName() +
                    "] 修改银行资产，当前的资产为：" + (this.asset / 100.0));
        } catch (Exception e) {
        } finally {
            this.readWriteLock.writeLock().unlock();    // 释放写锁
        }
    }

    public String toString() {    // 读锁操作方法
        this.readWriteLock.readLock().lock();    // 共享读锁
        try {
            TimeUnit.MILLISECONDS.sleep(100);    // 模拟延迟
            return "[" + Thread.currentThread().getName() + "] 账户名称：" + this.name +
                    ", 账户余额：" + (this.asset / 100.0);
        } catch (Exception e) {
            return null;
        } finally {
            this.readWriteLock.readLock().unlock();    // 释放读锁
        }
    }
}

public class YootkDemo6 {
    public static void main(String[] args) throws Exception {
        Account account = new Account("李兴华", 0); // 创建账户
        int money[] = new int[] { 110, 230, 10_000 }; // 存款金额（分）
        for (int x = 0; x < 10; x++) { // 循环创建线程
            if (x % 2 == 0) { // 启动存储线程
                new Thread(() -> {
                    for (int y = 0; y < money.length; y++) {
                        account.save(money[y]); // 存款操作
                    }
                }, "存款者 - " + x).start(); // 线程启动
            } else {
                new Thread(() -> {
                    while (true) { // 持续查询
                        System.out.println(account); // 查询操作
                    }
                }, "查询者 - " + x).start(); // 线程启动
            }
        }
    }
}